package com.neusoft.approveserver.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.inject.internal.asm.$ClassWriter;
import com.neusoft.approveserver.dto.ApprovalAdd;
import com.neusoft.approveserver.dto.ApprovalStatusUpdate;
import com.neusoft.approveserver.dto.ChanceSearchRole;
import com.neusoft.approveserver.dto.RespBean;
import com.neusoft.approveserver.entity.Approval;
import com.neusoft.approveserver.entity.Chance;
import com.neusoft.approveserver.entity.ChanceApproval;
import com.neusoft.approveserver.mapper.ApprovalMapper;
import com.neusoft.approveserver.mapper.ChanceApprovalMapper;
import com.neusoft.approveserver.mapper.ChanceMapper;
import com.neusoft.approveserver.service.IApprovalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.RecursiveTask;

/**
 * <p>
 * 机会审批记录表 服务实现类
 * </p>
 *
 * @author victor
 * @since 2021-07-18
 */
@Service
public class ApprovalServiceImpl extends ServiceImpl<ApprovalMapper, Approval> implements IApprovalService {
    @Autowired
    ApprovalMapper approvalMapper;

    @Autowired
    ChanceApprovalMapper chanceApprovalMapper;

    @Autowired
    ChanceMapper chanceMapper;
    @Override
    public RespBean addChanceApproval(ApprovalAdd approvalAdd) {
        RespBean respBean = RespBean.ok(200, "Operation successful!");
        String handle = approvalAdd.getApproval().getApprovalHandleAdvice();
        String role = approvalAdd.getRole();
        Approval approval = approvalAdd.getApproval();
        if(role.equals("MARKET_MGR")){
            if(handle.equals("return")){
                approval.setApprovalStatus("Returned");
            }else if(handle.equals("reject")){
                approval.setApprovalStatus("Rejected");
            }else if(handle.equals("approve")){
                approval.setApprovalStatus("Approved By MARKET_MGR");
            }
        }else if(role.equals("BUSSINESS_MGR")){
            if(handle.equals("reject")){
                approval.setApprovalStatus("Rejected");
            }else if(handle.equals("approve")){
                approval.setApprovalStatus("Approved");
                respBean.setMsg("Approved");
            }
        }

        Date d = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String sdate = sdf.format(d);

        approval.setApprovalTime(sdate);
        approval.setApprovalUptime(sdate);

        approvalMapper.insert(approval);
        Integer approvalId = approval.getApprovalId();
        ChanceApproval chanceApproval = new ChanceApproval();
        chanceApproval.setApprovalId(approvalId);
        chanceApproval.setChanceId(approvalAdd.getChanceId());
        chanceApprovalMapper.insert(chanceApproval);
        return respBean;
    }

    @Override
    public RespBean queryAllApproval() {
        List<Approval> approvalList = approvalMapper.selectList(null);
        return RespBean.ok(200,"Search success",approvalList);
    }

    @Override
    public RespBean getApprovalByChanceId(Integer chanceId) {
        RespBean respBean = RespBean.ok(200, "Approval found successfully!");
        LambdaQueryWrapper<ChanceApproval> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ChanceApproval::getChanceId, chanceId);
        List<ChanceApproval> chanceApprovals = new ArrayList<>();
        chanceApprovals = chanceApprovalMapper.selectList(wrapper);
        List<Approval> approvals = new ArrayList<>();
        if(chanceApprovals.size() > 0){
            for(ChanceApproval chanceApproval : chanceApprovals){
                approvals.add(approvalMapper.selectById(chanceApproval.getApprovalId()));
            }
        }
        respBean.setObj(approvals);
        return respBean;
    }

    @Override
    public RespBean getLatestApprovalByChanceId(Integer chanceId) {
        RespBean respBean = RespBean.ok(200, "Approval found successfully!");
        LambdaQueryWrapper<ChanceApproval> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ChanceApproval::getChanceId, chanceId);
        List<ChanceApproval> chanceApprovals = new ArrayList<>();
        chanceApprovals = chanceApprovalMapper.selectList(wrapper);
        List<Approval> approvals = new ArrayList<>();
        if(chanceApprovals.size() > 0){
            for(ChanceApproval chanceApproval : chanceApprovals){
                Approval approval = approvalMapper.selectById(chanceApproval.getApprovalId());
                if(approval != null)
                approvals.add(approvalMapper.selectById(chanceApproval.getApprovalId()));
            }
            approvals.sort(new Comparator<Approval>() {
                @Override
                public int compare(Approval o1, Approval o2) {
                    return o2.getApprovalTime().compareTo(o1.getApprovalTime());
                }
            });
            respBean.setObj(approvals.get(0));
        }
        return respBean;
    }

    @Override
    public RespBean updateLatestApprovalByChanceId(ApprovalStatusUpdate approvalStatusUpdate) {
        Integer chanceId = approvalStatusUpdate.getChanceId();
        RespBean respBean = RespBean.ok(200, "Approval updated successfully!");
        LambdaQueryWrapper<ChanceApproval> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(ChanceApproval::getChanceId, chanceId);
        List<ChanceApproval> chanceApprovals = new ArrayList<>();
        chanceApprovals = chanceApprovalMapper.selectList(wrapper);
        List<Approval> approvals = new ArrayList<>();
        if(chanceApprovals.size() > 0){
            for(ChanceApproval chanceApproval : chanceApprovals){
                approvals.add(approvalMapper.selectById(chanceApproval.getApprovalId()));
            }
            approvals.sort(new Comparator<Approval>() {
                @Override
                public int compare(Approval o1, Approval o2) {
                    return o2.getApprovalTime().compareTo(o1.getApprovalTime());
                }
            });
            Approval latestApproval = approvals.get(0);
            latestApproval.setApprovalStatus(approvalStatusUpdate.getStatus());
            approvalMapper.updateById(latestApproval);
        }
        return respBean;
    }

    @Override
    public RespBean searchChanceByUserRole(ChanceSearchRole chanceSearchRole) {
        RespBean respBean = RespBean.ok(200, "Chance found successfully!");
        List<Approval> approvals = getAllLatestApproval();
        List<Chance> chances = new ArrayList<>();
        if(approvals.size() > 0){
            List<Integer> approvalIds = new ArrayList<>();
            for(Approval approval : approvals) {
                if(chanceSearchRole.getRole().equals("BUSSINESS_MGR") && approval.getApprovalStatus().equals("Approved By MARKET_MGR")){
                    approvalIds.add(approval.getApprovalId());
                }else if(chanceSearchRole.getRole().equals("MARKET_MGR") && approval.getApprovalStatus().equals("Waiting For Approval")){
                    approvalIds.add(approval.getApprovalId());
                }else if(chanceSearchRole.getRole().equals("ADMIN")){
                    approvalIds.add(approval.getApprovalId());
                }
            }
            List<ChanceApproval> chanceApprovals = new ArrayList<>();
            if(approvalIds.size() > 0){
                LambdaQueryWrapper<ChanceApproval> chanceApprovalWrapper = Wrappers.lambdaQuery();
                chanceApprovalWrapper.in(ChanceApproval::getApprovalId, approvalIds);
                chanceApprovals = chanceApprovalMapper.selectList(chanceApprovalWrapper);
            }
            Set<Integer> chanceIds = new HashSet<>();
            for(ChanceApproval chanceApproval : chanceApprovals){
                chanceIds.add(chanceApproval.getChanceId());
            }
            if(chanceIds.size() > 0)
            chances = chanceMapper.selectBatchIds(chanceIds);
        }
        respBean.setObj(chances);
        return respBean;
    }

    List<Approval> getAllLatestApproval(){
        LambdaQueryWrapper<ChanceApproval> wrapper = Wrappers.lambdaQuery();
        List<ChanceApproval> chanceApprovals = chanceApprovalMapper.selectList(wrapper);
        Map<Integer, List<Approval>> approvalMp = new HashMap<>();
        for(ChanceApproval chanceApproval : chanceApprovals){
            if(!approvalMp.containsKey(chanceApproval.getChanceId())){
                approvalMp.put(chanceApproval.getChanceId(), new ArrayList<>());
            }
            Approval approval = approvalMapper.selectById(chanceApproval.getApprovalId());
            if(approval != null)
            approvalMp.get(chanceApproval.getChanceId()).add(approval);
        }
        List<Approval> ans = new ArrayList<>();
        for(Integer key : approvalMp.keySet()){
            approvalMp.get(key).sort(new Comparator<Approval>() {
                @Override
                public int compare(Approval o1, Approval o2) {
                    return o2.getApprovalTime().compareTo(o1.getApprovalTime());
                }
            });
            if(approvalMp.get(key).size() > 0)
                ans.add(approvalMp.get(key).get(0));
        }
        return ans;
    }

}
